import {BrowserWindow, dialog, ipcMain} from 'electron'
import path from 'path'
import {execCommand, getCurrentTime, loadDir, readResultLines} from './utils'
import {localConfig} from './storage'

const fixPath = require('fix-path')

const fs = require('fs')
const util = require('util')
const execPromise = util.promisify(require('child_process').exec)

class ManagePlugin {
  mainWindow: BrowserWindow

  constructor(mainWindow) {
    this.mainWindow = mainWindow
    //注册事件
    ipcMain.handle('getAppVersionMain', (event) => this.getAppVersionMain())
    ipcMain.handle('getProjectDirsMain', (event, args) => this.getProjectDirsMain(args))
    ipcMain.handle('loadProjectDirsMain', (event, args) => this.loadProjectDirsMain(args))
    ipcMain.handle('selectDirPathMain', (event, args) => this.selectDirPathMain(args))
    ipcMain.handle('saveProjectPathMain', (event, args) => this.saveProjectPathMain(args))
    ipcMain.handle('saveProjectFlagMain', (event, args) => this.saveProjectFlagMain(args))
    ipcMain.handle('saveDevToolsMain', (event, args) => this.saveDevToolsMain(args))
    ipcMain.handle('getProjectPathMain', (event, args) => this.getProjectPathMain(args))
    ipcMain.handle('getProjectFlagMain', (event, args) => this.getProjectFlagMain(args))
    ipcMain.handle('getDevToolsMain', (event, args) => this.getDevToolsMain(args))
    ipcMain.handle('getPlatformMain', (event, args) => this.getPlatformMain(args))
    ipcMain.handle('importManageDataMain', (event, args) => this.importManageDataMain(args))
    ipcMain.handle('exportManageDataMain', (event, args) => this.exportManageDataMain(args))
    ipcMain.handle('closeAppMain', (event, args) => this.closeAppMain(args))
    ipcMain.on('runCmdMain', (event, args) => this.runCmdMain(args))
    //修复mac系统上面的Path环境变量的问题
    // console.log('fixPath===', process.env.PATH)
    fixPath()
    // console.log('fixPath===', process.env.PATH)
  }

  //更新window属性
  updateWindow(mainWindow) {
    this.mainWindow = mainWindow
  }

  //从package.json文件中获取版本号
  getAppVersionMain() {
    let version
    try {
      let packageObj = require(path.join(__dirname, '..', '..', 'package.json'))
      version = packageObj.version
    } catch (e) {
      console.error(e)
    }
    return version
  }

  //获取项目的文件夹名称
  getProjectDirsMain(args) {
    let projectDirObj = {}
    let projectList = this.getProjectPathMain()
    if (!projectList) return projectDirObj
    projectList = JSON.parse(projectList)
    projectList.forEach((item) => {
      let dirName = item.path
      projectDirObj[dirName] = loadDir(item.path, item.level, item.filter || [])
    })
    return projectDirObj
  }

  //获取项目的文件夹下面的文件夹
  loadProjectDirsMain(args = '{}') {
    args = JSON.parse(args)
    let {path, level, filter} = args
    return loadDir(path, level, filter)
  }

  //保存项目路径到缓存
  saveProjectPathMain(projectPathStr = '{}') {
    return localConfig.setItem('projectPathStr', projectPathStr)
  }

  //保存项目路径到缓存
  saveProjectFlagMain(projectFlagStr = '{}') {
    return localConfig.setItem('projectFlagStr', projectFlagStr)
  }

  //保存项目路径到缓存
  saveDevToolsMain(devToolsStr = 'webstorm') {
    return localConfig.setItem('devToolsStr', devToolsStr)
  }

  //获取缓存的项目路径
  getProjectPathMain(): string {
    return localConfig.getItem('projectPathStr')
  }

  //获取缓存的项目路径
  getDevToolsMain(): string {
    return localConfig.getItem('devToolsStr')
  }

  //系统
  getPlatformMain(): string {
    if (process.platform === 'darwin') {
      console.log('运行在 macOS 上')
      return 'mac'
    } else if (process.platform === 'win32') {
      console.log('运行在 Windows 上')
      return 'window'
    } else {
      console.log('运行在其他操作系统上')
      return 'other'
    }
  }

  //导入项目配置
  async importManageDataMain(arg) {
    if (!arg.projectPathStr && !arg.projectFlagStr) {
      return {result: false, message: '导入参数配置错误！'}
    }
    const {filePaths} = await dialog.showOpenDialog({
      properties: ['openFile'],
      filters: [{name: 'JSON Files', extensions: ['json']}]
    })
    if (filePaths.length === 0) return {result: false, message: '未选择文件！'}

    const promises = fs.promises
    const data = await promises.readFile(filePaths[0], 'utf8')
    const manageData = JSON.parse(data)
    if (arg.projectPathStr && manageData.projectPathStr) {
      localConfig.setItem('projectPathStr', manageData.projectPathStr)
      return {result: true, message: '导入成功！'}
    }
    if (arg.projectFlagStr && manageData.projectFlagStr) {
      localConfig.setItem('projectFlagStr', manageData.projectFlagStr)
      return {result: true, message: '导入成功！'}
    }
    if (
      (arg.projectPathStr && !manageData.projectPathStr) ||
      (arg.projectFlagStr && !manageData.projectFlagStr)
    ) {
      return {result: true, message: '导入文件选择错误！'}
    }
  }

  //导出项目配置
  async exportManageDataMain(arg) {
    let projectPathStr, projectFlagStr, saveTitle, defaultPath
    if (!arg.projectPathStr && !arg.projectFlagStr) {
      return {result: false, message: '导出参数配置错误！'}
    }
    if (arg.projectPathStr) {
      projectPathStr = localConfig.getItem('projectPathStr')
      saveTitle = '保存项目管理配置数据'
      defaultPath = '项目管理配置.json'
    }
    if (arg.projectFlagStr) {
      projectFlagStr = localConfig.getItem('projectFlagStr')
      saveTitle = '保存项目标签配置数据'
      defaultPath = '项目标签配置.json'
    }
    //选择保存文件夹
    const {filePath} = await dialog.showSaveDialog({
      title: saveTitle,
      defaultPath: defaultPath,
      filters: [
        {name: 'JSON Files', extensions: ['json']},
        {name: 'All Files', extensions: ['*']}
      ]
    })
    if (!filePath) return // 用户取消了保存
    const jsonData = {
      projectPathStr,
      projectFlagStr
    }
    try {
      fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2))
      console.log('文件已保存:', filePath)
      return {result: true, message: '导出成功！'}
    } catch (err) {
      console.error('保存文件失败:', err)
      return {result: true, message: '导出失败！'}
    }
  }

  closeAppMain(args) {
    this.mainWindow.close()
  }

  //获取缓存的项目标签
  getProjectFlagMain(arg): string {
    let projectFlagStrValue = localConfig.getItem('projectFlagStr') || '[]'
    let projectFlagData = JSON.parse(projectFlagStrValue)
    let addFirstLevelBtnIndex = projectFlagData.findIndex((item) => item.flag == 'addFirstLevelBtn')
    if (arg && arg.removeAddFlag && addFirstLevelBtnIndex != -1) {
      projectFlagData.splice(addFirstLevelBtnIndex, 1)
    }
    return projectFlagData
  }

  //选择项目路径
  selectDirPathMain(arg) {
    return new Promise((resolve, reject) => {
      dialog
        .showOpenDialog(this.mainWindow, {
          properties: ['openDirectory']
        })
        .then((result) => {
          if (!result.canceled) {
            console.log('selectDirPathMain', result.filePaths[0]) // 选择的文件夹路径
            return resolve(result.filePaths[0])
          }
          resolve(null)
        })
        .catch((err) => {
          console.error('selectDirPathMain', err)
        })
    })
  }

  //执行cmd命令
  async runCmdMain(commandList = []) {
    this.sendMessageToRender(`data:${getCurrentTime()} #### runCmd start\n\n`)
    // this.sendMessageToRender(path.join(__dirname, 'path-to-executable'))

    //循环执行多条命令
    for (let i = 0; i < commandList.length; i++) {
      let commandItem = commandList[i]
      console.log('commandItem', commandItem)
      try {
        this.sendMessageToRender(`data:${getCurrentTime()} #### ${commandItem}\n\n`)
        let result = await execCommand(commandItem)
        let {stdout, error, stderr} = result
        console.log('result====', i, result)
        readResultLines(stdout || stderr || '执行完成！').forEach((item) =>
          this.sendMessageToRender(`data:${getCurrentTime(true)}==== ${item}\n\n`)
        )
      } catch (e) {
        readResultLines(e.message).forEach((item) =>
          this.sendMessageToRender(`data:${getCurrentTime(true)}==== ${item}\n\n`)
        )
        break
      }
    }
    //结束标志
    this.sendMessageToRender(`data:${getCurrentTime()} #### runCmd end\n\n`)
  }

  //向渲染进程发送消息
  sendMessageToRender(msg) {
    this.mainWindow.webContents.send('mainToRendererMsg', msg)
  }
}

//单例模式的插件管理对象
let managePluginInstance: ManagePlugin = null

//创建插件管理对象
export const createManagePlugin = (mainWindow) => {
  if (!managePluginInstance) managePluginInstance = new ManagePlugin(mainWindow)
  return managePluginInstance
}

//更新插件管理对象的-window对象
export const updateManageWindow = (mainWindow) => {
  console.log('updateManageWindow===', mainWindow)
  if (managePluginInstance) managePluginInstance.updateWindow(mainWindow)
}
